package com.code.starter.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.util.StrUtil;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class ExcelExportUtil {
	
	/**
	 * excel模板导出
	 * @param response
	 * @param title	表头
	 * @param fileName	文件名称
	 */
	public static void exportExlTemplate(HttpServletResponse response,String[] title,String fileName) {
		if (StrUtil.isBlank(fileName)) {
			fileName = "导出数据";
		}
		exportData(response, title, null, fileName);
	}
	
	public static void exportExlData(HttpServletResponse response,String[] title,List<Map<String, Object>> data,String fileName) {
		if (StrUtil.isBlank(fileName)) {
			fileName = "导出数据";
		}
		exportData(response, title, data, fileName);
	}
	
	/**
	 * excel数据导出
	 * @param response
	 * @param title	表头
	 * @param data	数据
	 * @param fileName	文件内容
	 */
	private static void exportData(HttpServletResponse response,String[] title,List<Map<String, Object>> data,String fileName) {
		
		HSSFWorkbook wb = new HSSFWorkbook();//创建excel表
		HSSFSheet sheet = wb.createSheet(fileName);
		sheet.setDefaultColumnWidth(20);//设置默认行宽

		HSSFFont fontStyle = wb.createFont();

		//标题样式（加粗，垂直居中）
		HSSFCellStyle cellStyle2 = wb.createCellStyle();
		cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
		cellStyle2.setFont(fontStyle);
		//设置边框样式
		cellStyle2.setBorderBottom(BorderStyle.THIN); //下边框
		cellStyle2.setBorderLeft(BorderStyle.THIN);//左边框
		cellStyle2.setBorderTop(BorderStyle.THIN);//上边框
		cellStyle2.setBorderRight(BorderStyle.THIN);//右边框

		//字段样式（垂直居中）
		HSSFCellStyle cellStyle3 = wb.createCellStyle();
		cellStyle3.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
		//设置边框样式
		cellStyle3.setBorderBottom(BorderStyle.THIN); //下边框
		cellStyle3.setBorderLeft(BorderStyle.THIN);//左边框
		cellStyle3.setBorderTop(BorderStyle.THIN);//上边框
		cellStyle3.setBorderRight(BorderStyle.THIN);//右边框

		//创建标题
		HSSFRow rowTitle = sheet.createRow(0);
		rowTitle.setHeightInPoints(20);

		HSSFCell hc;
		for (int i = 0; i < title.length; i++) {
			hc = rowTitle.createCell(i);
			String titleString = title[i];
			hc.setCellValue(titleString.substring(0, titleString.indexOf(":")));
			hc.setCellStyle(cellStyle2);
		}
		try {
			if (CollUtil.isNotEmpty(data)) {
				//创建表格数据
				int i = 1;
				for (Map<String, Object> theMap : data) {
					HSSFRow rowBody = sheet.createRow(i);
					rowBody.setHeightInPoints(20);
					for (int j = 0; j < title.length; j++) {
						String titleString = title[j];
						String mapKey = titleString.substring(titleString.indexOf(":") + 1,titleString.length());

						hc = rowBody.createCell(j);
						hc.setCellStyle(cellStyle3);
						Object theValue = theMap.get(mapKey);
						if (theValue == null) {
							hc.setCellValue("");
						}else {
							if (theValue.getClass().equals(Date.class)) {
								if ((mapKey.endsWith("Time") || mapKey.equals("updated") || mapKey.equals("created"))) {
									hc.setCellValue(DateUtil.formatDateTime((Date) theValue));
								} else if (mapKey.endsWith("Date")) {
									hc.setCellValue(DateUtil.formatDate((Date) theValue));
								} else if (mapKey.endsWith("Month")) {
									hc.setCellValue(DateUtil.format((Date) theValue, "yyyy-MM"));
								} 
							} else if(theValue.getClass().equals(BigDecimal.class)) {
								hc.setCellValue(String.format("%.2f", theValue).toString());
							} else {
								hc.setCellValue(theValue.toString());
							}
						}
					}
					i++;
				}
			}
			fileName = URLEncoder.encode(fileName, "UTF-8");
			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			response.setCharacterEncoding("utf8");
			response.setHeader("Content-Disposition", "attachment;filename=" + ";" + "filename*=utf-8''" + fileName + ".xlsx");
			wb.write(response.getOutputStream());
		} catch (Exception ex) {
			throw new ValidateException("数据导出异常");
		} finally{
			try {
				wb.close();
			} catch (IOException ex) {
				throw new ValidateException("数据导出异常");
			}
		}
	}
	
}
